#ifndef INTERRUPT_H
#define INTERRUPT_H

//*****************************************************************************
//
// If building with a C++ compiler, make all of the definitions in this header
// have a C binding.
//
//*****************************************************************************
#ifdef __cplusplus
extern "C" {
#endif

//*****************************************************************************
//
//! \addtogroup interrupt_api Interrupt
//! @{
//
//*****************************************************************************

#include <stdbool.h>
#include <stdint.h>
#include "inc/hw_ints.h"
#include "inc/hw_memmap.h"
#include "inc/hw_pie.h"
#include "inc/hw_types.h"
#include "cpu.h"
#include "debug.h"

#include "f28p65x_device.h"

#ifndef DOXYGEN_PDF_IGNORE

//*****************************************************************************
// IER  BIT Numbers define
//*****************************************************************************

#define PIC_GROUP1  0x0001
#define PIC_GROUP2  0x0002
#define PIC_GROUP3  0x0004
#define PIC_GROUP4  0x0008
#define PIC_GROUP5  0x0010
#define PIC_GROUP6  0x0020
#define PIC_GROUP7  0x0040
#define PIC_GROUP8  0x0080
#define PIC_GROUP9  0x0100
#define PIC_GROUP10 0x0200
#define PIC_GROUP11 0x0400
#define PIC_GROUP12 0x0800
#define PIC_TIMER1  0x1000
#define PIC_TIMER2  0x2000

//*****************************************************************************
// PIEIER  BIT Numbers define
//*****************************************************************************

// Lower PIE Group 1
#define PIE_BIT_RTOS      0x0001 // 1.1 - RTOS Interrupt
#define PIE_BIT_ADCA1     0x0002 // 1.2 - ADCA Interrupt 1
#define PIE_BIT_ADCB1     0x0004 // 1.3 - ADCB Interrupt 1
#define PIE_BIT_ADCC1     0x0008 // 1.4 - ADCC Interrupt 1
#define PIE_BIT_XINT1     0x0010 // 1.5 - XINT1 Interrupt
#define PIE_BIT_XINT2     0x0020 // 1.6 - XINT2 Interrupt
#define PIE_BIT_TIMER0    0x0040 // 1.7 - Timer 0 Interrupt
#define PIE_BIT_WAKE      0x0080 // 1.8 - Halt Wakeup/Watchdog Interrupt
#define PIE_BIT_ADCF1     0x0100 // 1.9 - ADCF Interrupt 1
#define PIE_BIT_ADCF2     0x0100 // 1.10 - ADCF Interrupt 2
#define PIE_BIT_SYS_ERR   0x0200 // 1.11 - SYS ERROR Interrupt
#define PIE_BIT_BGCRC     0x0200 // 1.11 - BGCRC Interrupt
#define PIE_BIT_ECATSYNC0 0x0400 // 1.11 - ETHCAT SYNC 0 Interrupt
#define PIE_BIT_ECAT      0x0800 // 1.12 - ETHCAT Interrupt
#define PIE_BIT_CIPC0     0x1000 // 1.13 - CIPC 0 Interrupt
#define PIE_BIT_CIPC1     0x2000 // 1.14 - CIPC 1 Interrupt
#define PIE_BIT_CIPC2     0x4000 // 1.15 - CIPC 2 Interrupt
#define PIE_BIT_CIPC3     0x8000 // 1.16 - CIPC 3 Interrupt

// Lower PIE Group 2
#define PIE_BIT_EPWM1_TZ  0x0001 // 2.1 - ePWM1 Trip Zone Interrupt
#define PIE_BIT_EPWM2_TZ  0x0002 // 2.2 - ePWM2 Trip Zone Interrupt
#define PIE_BIT_EPWM3_TZ  0x0004 // 2.3 - ePWM3 Trip Zone Interrupt
#define PIE_BIT_EPWM4_TZ  0x0008 // 2.4 - ePWM4 Trip Zone Interrupt
#define PIE_BIT_EPWM5_TZ  0x0010 // 2.5 - ePWM5 Trip Zone Interrupt
#define PIE_BIT_EPWM6_TZ  0x0020 // 2.6 - ePWM6 Trip Zone Interrupt
#define PIE_BIT_EPWM7_TZ  0x0040 // 2.7 - ePWM7 Trip Zone Interrupt
#define PIE_BIT_EPWM8_TZ  0x0080 // 2.8 - ePWM8 Trip Zone Interrupt
#define PIE_BIT_EPWM9_TZ  0x0100 // 2.9 - ePWM9 Trip Zone Interrupt
#define PIE_BIT_EPWM10_TZ 0x0200 // 2.10 - ePWM10 Trip Zone Interrupt
#define PIE_BIT_EPWM11_TZ 0x0400 // 2.11 - ePWM11 Trip Zone Interrupt
#define PIE_BIT_EPWM12_TZ 0x0800 // 2.12 - ePWM12 Trip Zone Interrupt
#define PIE_BIT_EPWM13_TZ 0x1000 // 2.13 - ePWM13 Trip Zone Interrupt
#define PIE_BIT_EPWM14_TZ 0x2000 // 2.14 - ePWM14 Trip Zone Interrupt
#define PIE_BIT_EPWM15_TZ 0x4000 // 2.15 - ePWM15 Trip Zone Interrupt
#define PIE_BIT_EPWM16_TZ 0x8000 // 2.16 - ePWM16 Trip Zone Interrupt

// Lower PIE Group 3
#define PIE_BIT_EPWM1  0x0001 // 3.1 - ePWM1 Interrupt
#define PIE_BIT_EPWM2  0x0002 // 3.2 - ePWM2 Interrupt
#define PIE_BIT_EPWM3  0x0004 // 3.3 - ePWM3 Interrupt
#define PIE_BIT_EPWM4  0x0008 // 3.4 - ePWM4 Interrupt
#define PIE_BIT_EPWM5  0x0010 // 3.5 - ePWM5 Interrupt
#define PIE_BIT_EPWM6  0x0020 // 3.6 - ePWM6 Interrupt
#define PIE_BIT_EPWM7  0x0040 // 3.7 - ePWM7 Interrupt
#define PIE_BIT_EPWM8  0x0080 // 3.8 - ePWM8 Interrupt
#define PIE_BIT_EPWM9  0x0100 // 3.9 - ePWM9 Interrupt
#define PIE_BIT_EPWM10 0x0200 // 3.10 - ePWM10 Interrupt
#define PIE_BIT_EPWM11 0x0400 // 3.11 - ePWM11 Interrupt
#define PIE_BIT_EPWM12 0x0800 // 3.12 - ePWM12 Interrupt
#define PIE_BIT_EPWM13 0x1000 // 3.13 - ePWM13 Interrupt
#define PIE_BIT_EPWM14 0x2000 // 3.14 - ePWM14 Interrupt
#define PIE_BIT_EPWM15 0x4000 // 3.15 - ePWM15 Interrupt
#define PIE_BIT_EPWM16 0x8000 // 3.16 - ePWM16 Interrupt

// Lower PIE Group 4
#define PIE_BIT_ECAP1   0x0001 // 4.1 - eCAP1 Interrupt
#define PIE_BIT_ECAP2   0x0002 // 4.2 - eCAP2 Interrupt
#define PIE_BIT_ECAP3   0x0004 // 4.3 - eCAP3 Interrupt
#define PIE_BIT_ECAP4   0x0008 // 4.4 - eCAP4 Interrupt
#define PIE_BIT_ECAP5   0x0010 // 4.5 - eCAP5 Interrupt
#define PIE_BIT_ECAP6   0x0020 // 4.6 - eCAP6 Interrupt
#define PIE_BIT_ECAP7   0x0040 // 4.7 - eCAP7 Interrupt
#define PIE_BIT_ADCD1   0x0080 // 4.8 - ADCD1 Interrupt
#define PIE_BIT_FSITXA1 0x0100 // 4.9 - FSITXA Interrupt 1
#define PIE_BIT_FSITXA2 0x0200 // 4.10 - FSITXA Interrupt 2
#define PIE_BIT_FSITXB1 0x0400 // 4.11 - FSITXB Interrupt 1
#define PIE_BIT_FSITXB2 0x0800 // 4.12 - FSITXB Interrupt 2
#define PIE_BIT_FSIRXA1 0x1000 // 4.13 - FSIRXA Interrupt 1
#define PIE_BIT_FSIRXA2 0x2000 // 4.14 - FSIRXA Interrupt 2
#define PIE_BIT_FSIRXB1 0x4000 // 4.15 - FSIRXB Interrupt 1
#define PIE_BIT_FSIRXB2 0x8000 // 4.16 - FSIRXB Interrupt 2

// Lower PIE Group 5
#define PIE_BIT_EQEP1     0x0001 // 5.1 - eQEP1 Interrupt
#define PIE_BIT_EQEP2     0x0002 // 5.2 - eQEP2 Interrupt
#define PIE_BIT_EQEP3     0x0004 // 5.3 - eQEP3 Interrupt
#define PIE_BIT_EQEP4     0x0008 // 5.4 - eQEP4 Interrupt
#define PIE_BIT_CLB1      0x0010 // 5.5 - CLB1 Interrupt
#define PIE_BIT_CLB2      0x0020 // 5.6 - CLB2 Interrupt
#define PIE_BIT_CLB3      0x0040 // 5.7 - CLB4 Interrupt
#define PIE_BIT_CLB4      0x0080 // 5.8 - CLB8 Interrupt
#define PIE_BIT_SDFM1     0x0100 // 5.9 - SDFM1 Interrupt
#define PIE_BIT_SDFM2     0x0200 // 5.10 - SDFM2 Interrupt
#define PIE_BIT_ECATSRT   0x0400 // 5.11 - ETHCAT RST Interrupt
#define PIE_BIT_ECATSYNC1 0x0800 // 5.12 - ETHCAT SYNC1 Interrupt
#define PIE_BIT_SDFM1DR1  0x1000 // 5.13 - SDFM1DR1 Interrupt
#define PIE_BIT_SDFM1DR2  0x2000 // 5.14 - SDFM1DR2 Interrupt
#define PIE_BIT_SDFM1DR3  0x4000 // 5.15 - SDFM1DR3 Interrupt
#define PIE_BIT_SDFM1DR4  0x8000 // 5.16 - SDFM1DR4 Interrupt

// Lower PIE Group 6
#define PIE_BIT_SPIA_RX  0x0001 // 6.1 - SPIA Receive Interrupt
#define PIE_BIT_SPIA_TX  0x0002 // 6.2 - SPIA Transmit Interrupt
#define PIE_BIT_SPIB_RX  0x0004 // 6.3 - SPIB Receive Interrupt
#define PIE_BIT_SPIB_TX  0x0008 // 6.4 - SPIB Transmit Interrupt
#define PIE_BIT_LINA     0x0010 // 6.5 - LINA Interrupt
#define PIE_BIT_ADCE1    0x0020 // 6.6 - ADCE1 Interrupt
#define PIE_BIT_LINB     0x0040 // 6.7 - LINB Interrupt
#define PIE_BIT_ADCE2    0x0080 // 6.8 - ADCE2 Interrupt
#define PIE_BIT_SPIC_RX  0x0100 // 6.9 - SPIC Receive Interrupt
#define PIE_BIT_SPIC_TX  0x0200 // 6.10 - SPIC Transmit Interrupt
#define PIE_BIT_SPID_RX  0x0400 // 6.11 - SPID Receive Interrupt
#define PIE_BIT_SPID_TX  0x0800 // 6.12 - SPID Transmit Interrupt
#define PIE_BIT_SDFM2DR1 0x1000 // 6.13 - SDFM2DR1 Interrupt
#define PIE_BIT_SDFM2DR2 0x2000 // 6.14 - SDFM2DR2 Interrupt
#define PIE_BIT_SDFM2DR3 0x4000 // 6.15 - SDFM2DR3 Interrupt
#define PIE_BIT_SDFM2DR4 0x8000 // 6.16 - SDFM2DR4 Interrupt

// Lower PIE Group 7
#define PIE_BIT_DMA_CH1  0x0001 // 7.1 - DMA Channel 1 Interrupt
#define PIE_BIT_DMA_CH2  0x0002 // 7.2 - DMA Channel 2 Interrupt
#define PIE_BIT_DMA_CH3  0x0004 // 7.3 - DMA Channel 3 Interrupt
#define PIE_BIT_DMA_CH4  0x0008 // 7.4 - DMA Channel 4 Interrupt
#define PIE_BIT_DMA_CH5  0x0010 // 7.5 - DMA Channel 5 Interrupt
#define PIE_BIT_DMA_CH6  0x0020 // 7.6 - DMA Channel 6 Interrupt
#define PIE_BIT_EQEP5    0x0040 // 7.7 - EQEP5 Interrupt
#define PIE_BIT_EQEP6    0x0080 // 7.8 - EQEP6 Interrupt
#define PIE_BIT_FSIRXC1  0x0100 // 7.9 - FSIRXC Interrupt 1
#define PIE_BIT_FSIRXC2  0x0200 // 7.10 - FSIRXC Interrupt 2
#define PIE_BIT_FSIRXD1  0x0400 // 7.11 - FSIRXD Interrupt 1
#define PIE_BIT_FSIRXD2  0x0800 // 7.12 - FSIRXD Interrupt 2
#define PIE_BIT_SDFM3DR1 0x1000 // 7.13 - SDFM3DR1 Interrupt
#define PIE_BIT_SDFM3DR2 0x2000 // 7.14 - SDFM3DR2 Interrupt
#define PIE_BIT_SDFM3DR3 0x4000 // 7.15 - SDFM3DR3 Interrupt
#define PIE_BIT_SDFM3DR4 0x8000 // 7.16 - SDFM3DR4 Interrupt

// Lower PIE Group 8
#define PIE_BIT_I2CA      0x0001 // 8.1 - I2CA Interrupt
#define PIE_BIT_I2CA_FIFO 0x0002 // 8.2 - I2CA  FIFO Interrupt
#define PIE_BIT_I2CB      0x0004 // 8.3 - I2CB Interrupt
#define PIE_BIT_I2CB_FIFO 0x0008 // 8.4 - I2CB  FIFO Interrupt
#define PIE_BIT_UARTA     0x0010 // 8.5 - UARTA Interrupt
#define PIE_BIT_UARTB     0x0020 // 8.6 - UARTB Interrupt
#define PIE_BIT_EPWM17_TZ 0x0040 // 8.7 - EPWM17 TZ Interrupt
#define PIE_BIT_EPWM18_TZ 0x0080 // 8.8 - EPWM18 TZ Interrupt
#define PIE_BIT_ADCG4     0x0100 // 8.9 - ADCG4 Interrupt
#define PIE_BIT_ADCF4     0x0200 // 8.10 - ADCF4 Interrupt
#define PIE_BIT_SDFM3     0x0400 // 8.11 - SDFM3 Interrupt
#define PIE_BIT_SDFM4     0x0800 // 8.12 - SDFM4 Interrupt
#define PIE_BIT_CLB5      0x1000 // 8.13 - CLB5 Interrupt
#define PIE_BIT_CLB6      0x2000 // 8.14 - CLB6 Interrupt
#define PIE_BIT_ADCE3     0x4000 // 8.15 - ADCE3 Interrupt
#define PIE_BIT_ADCE4     0x8000 // 8.16 - ADCE4 Interrupt

// Lower PIE Group 9
#define PIE_BIT_SCIA_RX         0x0001 // 9.1 - SCIA RX Interrupt
#define PIE_BIT_SCIA_TX         0x0002 // 9.2 - SCIA TX Interrupt
#define PIE_BIT_SCIB_RX         0x0004 // 9.3 - SCIB RX Interrupt
#define PIE_BIT_SCIB_TX         0x0008 // 9.4 - SCIB TX Interrupt
#define PIE_BIT_CANA            0x0010 // 9.5 - CANA Interrupt
#define PIE_BIT_ADCG_EVT        0x0020 // 9.6 - ADCG EVT Interrupt
#define PIE_BIT_EPWM17          0x0040 // 9.7 - EPWM17 Interrupt
#define PIE_BIT_EPWM18          0x0080 // 9.8 - EPWM18 Interrupt
#define PIE_BIT_MCANA           0x0100 // 9.9 - MCANA Interrupt
#define PIE_BIT_ADCG1           0x0200 // 9.10 - ADCG1 Interrupt
#define PIE_BIT_ADCG2           0x0400 // 9.11 - ADCG2 Interrupt
#define PIE_BIT_ADCG3           0x0800 // 9.12 - ADCG3 Interrupt
#define PIE_BIT_PMBUSA          0x1000 // 9.13 - PMBUSA Interrupt
#define PIE_BIT_AES_SINTREQUEST 0x2000 // 9.14 - AES_SINTREQUEST Interrupt
#define PIE_BIT_ADCE_EVT        0x4000 // 9.15 - ADCE_EVT Interrupt
#define PIE_BIT_EMIF            0x8000 // 9.16 - EMIF Interrupt

// Lower PIE Group 10
#define PIE_BIT_ADCA_EVT    0x0001 // 10.1 - ADCA Event Interrupt
#define PIE_BIT_ADCA2       0x0002 // 10.2 - ADCA Interrupt 2
#define PIE_BIT_ADCA3       0x0004 // 10.3 - ADCA Interrupt 3
#define PIE_BIT_ADCA4       0x0008 // 10.4 - ADCA Interrupt 4
#define PIE_BIT_ADCB_EVT    0x0010 // 10.5 - ADCB Event Interrupt
#define PIE_BIT_ADCB2       0x0020 // 10.6 - ADCB Interrupt 2
#define PIE_BIT_ADCB3       0x0040 // 10.7 - ADCB Interrupt 3
#define PIE_BIT_ADCB4       0x0080 // 10.8 - ADCB Interrupt 4
#define PIE_BIT_ADCC_EVT    0x0100 // 10.9 - ADCC Event Interrupt
#define PIE_BIT_ADCC2       0x0200 // 10.10 - ADCC Interrupt 2
#define PIE_BIT_ADCC3       0x0400 // 10.11 - ADCC Interrupt 3
#define PIE_BIT_ADCC4       0x0800 // 10.12 - ADCC Interrupt 4
#define PIE_BIT_ADCD2       0x1000 // 10.13 - ADCD Interrupt 2
#define PIE_BIT_ADCD3       0x2000 // 10.14 - ADCD Interrupt 3
#define PIE_BIT_ADCD4       0x4000 // 10.15 - ADCD Interrupt 4
#define PIE_BIT_ADCCHECKINT 0x8000 // 10.16 - ADC CHECK Interrupt

// Lower PIE Group 11
#define PIE_BIT_CLA1_1   0x0001 // 11.1 - CLA1 interrupts
#define PIE_BIT_CLA1_2   0x0002 // 11.2 - CLA2 interrupts
#define PIE_BIT_CLA1_3   0x0004 // 11.3 - CLA3 interrupts
#define PIE_BIT_CLA1_4   0x0008 // 11.4 - CLA4 interrupts
#define PIE_BIT_CLA1_5   0x0010 // 11.5 - CLA5 interrupts
#define PIE_BIT_CLA1_6   0x0020 // 11.6 - CLA6 interrupts
#define PIE_BIT_CLA1_7   0x0040 // 11.7 - CLA7 interrupts
#define PIE_BIT_CLA1_8   0x0080 // 11.8 - CLA8 interrupts
#define PIE_BIT_MCANB    0x0100 // 11.9 - MCANB interrupts
#define PIE_BIT_ADCD_EVT 0x0200 // 11.10 - ADCD EVT interrupts
#define PIE_BIT_ADH3     0x0400 // 11.10 - ADCH interrupts 3
#define PIE_BIT_ADH4     0x0800 // 11.11 - ADCH interrupts 4
#define PIE_BIT_SDFM4DR1 0x1000 // 11.13 - SDFM4DR1 Interrupt
#define PIE_BIT_SDFM4DR2 0x2000 // 11.14 - SDFM4DR2 Interrupt
#define PIE_BIT_SDFM4DR3 0x4000 // 11.15 - SDFM4DR3 Interrupt
#define PIE_BIT_SDFM4DR4 0x8000 // 11.16 - SDFM4DR4 Interrupt

// Lower PIE Group 12
#define PIE_BIT_XINT3         0x0001 // 12.1 - XINT3 Interrupt
#define PIE_BIT_XINT4         0x0002 // 12.2 - XINT4 Interrupt
#define PIE_BIT_XINT5         0x0004 // 12.3 - XINT5 Interrupt
#define PIE_BIT_CLA1_CICP0    0x0008 // 12.4 - CLA1_CIPC0 Interrupt
#define PIE_BIT_CLA1_CICP1    0x0010 // 12.5 - CLA1_CIPC1 Interrupt
#define PIE_BIT_CLA1_CICP2    0x0020 // 12.6 - CLA1_CIPC2 Interrupt
#define PIE_BIT_CLA1_CICP3    0x0040 // 12.7 - CLA1_CIPC3 Interrupt
#define PIE_BIT_ADCH_EVT      0x0080 // 12.8 - ADCH EVT Interrupt
#define PIE_BIT_ADCF3         0x0100 // 12.9 - ADCF Interrupt
#define PIE_BIT_ECAP6_2       0x0200 // 12.10 - HR ECAP6 Interrupt
#define PIE_BIT_ECAP7_2       0x0400 // 12.11 - HR ECAP7 Interrupt
#define PIE_BIT_ADCH1         0x0800 // 12.12 - ADCH Interrupt 1
#define PIE_BIT_ADCH2         0x1000 // 12.13 - ADCH Interrupt 2
#define PIE_BIT_ADCF_EVT      0x2000 // 12.14 - ADCF EVT Interrupt
#define PIE_BIT_CLA_OVERFLOW  0x4000 // 12.14 - CLA_OVERFLOW Interrupt
#define PIE_BIT_CLA_UNDERFLOW 0x8000 // 12.15 - CLA_UNDERFLOW Interrupt

// for compatable
//*****************************************************************************
//
// The following are values that can be passed to the Interrupt_enableInCPU()
// and Interrupt_disableInCPU() functions as the cpuInterrupt parameter.
//
//*****************************************************************************
#define INTERRUPT_CPU_INT1    0x1U    //!< CPU Interrupt Number 1
#define INTERRUPT_CPU_INT2    0x2U    //!< CPU Interrupt Number 2
#define INTERRUPT_CPU_INT3    0x4U    //!< CPU Interrupt Number 3
#define INTERRUPT_CPU_INT4    0x8U    //!< CPU Interrupt Number 4
#define INTERRUPT_CPU_INT5    0x10U   //!< CPU Interrupt Number 5
#define INTERRUPT_CPU_INT6    0x20U   //!< CPU Interrupt Number 6
#define INTERRUPT_CPU_INT7    0x40U   //!< CPU Interrupt Number 7
#define INTERRUPT_CPU_INT8    0x80U   //!< CPU Interrupt Number 8
#define INTERRUPT_CPU_INT9    0x100U  //!< CPU Interrupt Number 9
#define INTERRUPT_CPU_INT10   0x200U  //!< CPU Interrupt Number 10
#define INTERRUPT_CPU_INT11   0x400U  //!< CPU Interrupt Number 11
#define INTERRUPT_CPU_INT12   0x800U  //!< CPU Interrupt Number 12
#define INTERRUPT_CPU_INT13   0x1000U //!< CPU Interrupt Number 13
#define INTERRUPT_CPU_INT14   0x2000U //!< CPU Interrupt Number 14
#define INTERRUPT_CPU_DLOGINT 0x4000U //!< CPU Data Log Interrupt
#define INTERRUPT_CPU_RTOSINT 0x8000U //!< CPU RTOS Interrupt

// for compatable
//*****************************************************************************
//
// The following are values that can be passed to the Interrupt_clearACKGroup()
// function as the group parameter.
//
//*****************************************************************************
#define INTERRUPT_ACK_GROUP1  0x1U   //!< Acknowledge PIE Interrupt Group 1
#define INTERRUPT_ACK_GROUP2  0x2U   //!< Acknowledge PIE Interrupt Group 2
#define INTERRUPT_ACK_GROUP3  0x4U   //!< Acknowledge PIE Interrupt Group 3
#define INTERRUPT_ACK_GROUP4  0x8U   //!< Acknowledge PIE Interrupt Group 4
#define INTERRUPT_ACK_GROUP5  0x10U  //!< Acknowledge PIE Interrupt Group 5
#define INTERRUPT_ACK_GROUP6  0x20U  //!< Acknowledge PIE Interrupt Group 6
#define INTERRUPT_ACK_GROUP7  0x40U  //!< Acknowledge PIE Interrupt Group 7
#define INTERRUPT_ACK_GROUP8  0x80U  //!< Acknowledge PIE Interrupt Group 8
#define INTERRUPT_ACK_GROUP9  0x100U //!< Acknowledge PIE Interrupt Group 9
#define INTERRUPT_ACK_GROUP10 0x200U //!< Acknowledge PIE Interrupt Group 10
#define INTERRUPT_ACK_GROUP11 0x400U //!< Acknowledge PIE Interrupt Group 11
#define INTERRUPT_ACK_GROUP12 0x800U //!< Acknowledge PIE Interrupt Group 12
#endif

extern uint32_t PIEVECTTABLE_BASE;

//*****************************************************************************
//
// Prototypes for the APIs.
//
//*****************************************************************************
//*****************************************************************************
//
//! \internal
//! The default interrupt handler.
//!
//! This is the default interrupt handler.  The Interrupt_initVectorTable()
//! function sets all vectors to this function.  Also, when an interrupt is
//! unregistered using the Interrupt_unregister() function, this handler takes
//! its place.  This should never be called during normal operation.
//!
//! The ESTOP0 statement is for debug purposes only. Remove and replace with an
//! appropriate error handling routine for your program.
//!
//! \return None.
//
//*****************************************************************************
extern void Interrupt_defaultHandler(void);

//*****************************************************************************
//
//! \internal
//! The default illegal instruction trap interrupt handler.
//!
//! This is the default interrupt handler for an illegal instruction trap
//! (ITRAP).  The Interrupt_initVectorTable() function sets the appropriate
//! vector to this function.  This should never be called during normal
//! operation.
//!
//! The ESTOP0 statement is for debug purposes only.  Remove and replace with
//! an appropriate error handling routine for your program.
//!
//! \return None.
//
//*****************************************************************************
extern void Interrupt_illegalOperationHandler(void);

//*****************************************************************************
//
//! \internal
//! The default non-maskable interrupt handler.
//!
//! This is the default interrupt handler for a non-maskable interrupt (NMI).
//! The Interrupt_initVectorTable() function sets the appropriate vector to
//! this function.  This should never be called during normal operation.
//!
//! The ESTOP0 statement is for debug purposes only. Remove and replace with an
//! appropriate error handling routine for your program.
//!
//! \return None.
//
//*****************************************************************************
extern void Interrupt_nmiHandler(void);

//*****************************************************************************
//
//! Allows the CPU to process interrupts.
//!
//! This function clears the global interrupt mask bit (INTM) in the CPU,
//! allowing the processor to respond to interrupts.
//!
//! \return Returns \b true if interrupts were disabled when the function was
//! called or \b false if they were initially enabled.
//
//*****************************************************************************
static inline bool Interrupt_enableGlobal(void)
{
    //
    // Enable processor interrupts.
    //
    bool val     = ExpRegs.INTM;
    ExpRegs.INTM = 0;
    return val ? true : false;
}

//*****************************************************************************
//
//! Stops the CPU from processing interrupts.
//!
//! This function sets the global interrupt mask bit (INTM) in the CPU,
//! preventing the processor from receiving maskable interrupts.
//!
//! \return Returns \b true if interrupts were already disabled when the
//! function was called or \b false if they were initially enabled.
//
//*****************************************************************************
static inline bool Interrupt_disableGlobal(void)
{
    //
    // Disable processor interrupts.
    //
    bool val     = ExpRegs.INTM;
    ExpRegs.INTM = 1;
    return val ? true : false;
}

//*****************************************************************************
//
//! Registers a function to be called when an interrupt occurs.
//!
//! \param interruptNumber specifies the interrupt in question.
//! \param handler is a pointer to the function to be called.
//!
//! This function is used to specify the handler function to be called when the
//! given interrupt is asserted to the processor.  When the interrupt occurs,
//! if it is enabled (via Interrupt_enable()), the handler function will be
//! called in interrupt context.  Since the handler function can preempt other
//! code, care must be taken to protect memory or peripherals that are accessed
//! by the handler and other non-handler code.
//!
//! The available \e interruptNumber values are supplied in
//! <tt>inc/hw_ints.h</tt>.
//!
//! \note This function assumes that the PIE has been enabled. See
//! Interrupt_initModule().
//!
//! \return None.
//
//*****************************************************************************
static inline void Interrupt_register(uint32_t interruptNumber, void (*handler)(void))
{
    Uint32 tableindex, address;

    //
    // tableindex = interruptNumber[15:8] * 16 + interruptNumber[7:0] - 1
    //
    tableindex = (((interruptNumber >> 8) & 0xFF) << 4) + ((interruptNumber & 0xFF) - 1);
    address    = (Uint32)(&PIEVECTTABLE_BASE) + (tableindex << 2);

    //
    // Copy ISR address into PIE table
    //
    EALLOW;
    HWREG(address) = (uint32_t)handler;
    EDIS;
}

//*****************************************************************************
//
//! Unregisters the function to be called when an interrupt occurs.
//!
//! \param interruptNumber specifies the interrupt in question.
//!
//! This function is used to indicate that a default handler
//! Interrupt_defaultHandler() should be called when the given interrupt is
//! asserted to the processor.  Call Interrupt_disable() to disable
//! the interrupt before calling this function.
//!
//! The available \e interruptNumber values are supplied in
//! <tt>inc/hw_ints.h</tt>.
//!
//! \sa Interrupt_register() for important information about registering
//! interrupt handlers.
//!
//! \return None.
//
//*****************************************************************************
static inline void Interrupt_unregister(uint32_t interruptNumber)
{
    Uint32 tableindex, address;

    //
    // tableindex = interruptNumber[15:8] * 16 + interruptNumber[7:0] - 1
    //
    tableindex = (((interruptNumber >> 8) & 0xFF) << 4) + ((interruptNumber & 0xFF) - 1);
    address    = (Uint32)(&PIEVECTTABLE_BASE) + (tableindex << 2);

    //
    // Copy ISR address into PIE table
    //
    EALLOW;
    HWREG(address) = (Uint32)Interrupt_defaultHandler;
    EDIS;
}

//*****************************************************************************
//

//*****************************************************************************
//
//! Acknowledges PIE Interrupt Group
//!
//! \param group specifies the interrupt group to be acknowledged.
//!
//! The specified interrupt group is acknowledged and clears any interrupt
//! flag within that respective group.
//!
//! The \e group parameter must be a logical OR of the following:
//! \b INTERRUPT_ACK_GROUP1, \b INTERRUPT_ACK_GROUP2, \b INTERRUPT_ACK_GROUP3
//! \b INTERRUPT_ACK_GROUP4, \b INTERRUPT_ACK_GROUP5, \b INTERRUPT_ACK_GROUP6
//! \b INTERRUPT_ACK_GROUP7, \b INTERRUPT_ACK_GROUP8, \b INTERRUPT_ACK_GROUP9
//! \b INTERRUPT_ACK_GROUP10, \b INTERRUPT_ACK_GROUP11,
//! \b INTERRUPT_ACK_GROUP12.
//!
//! \return None.
//
//*****************************************************************************
static inline void Interrupt_clearACKGroup(uint16_t group)
{
    //
    // Set interrupt group acknowledge bits
    //
}

//! Initializes the PIE control registers by setting them to a known state.
//!
//! This function initializes the PIE control registers. After globally
//! disabling interrupts and enabling the PIE, it clears all of the PIE
//! interrupt enable bits and interrupt flags.
//!
//! \return None.
//
//*****************************************************************************
extern void Interrupt_initModule(void);

//*****************************************************************************
//
//! Initializes the PIE vector table by setting all vectors to a default
//! handler function.
//!
//! \return None.
//
//*****************************************************************************
extern void Interrupt_initVectorTable(void);

//*****************************************************************************
//
//! Enables an interrupt.
//!
//! \param interruptNumber specifies the interrupt to be enabled.
//!
//! The specified interrupt is enabled in the interrupt controller.  Other
//! enables for the interrupt (such as at the peripheral level) are unaffected
//! by this function.
//!
//! The available \e interruptNumber values are supplied in
//! <tt>inc/hw_ints.h</tt>.
//!
//! \return None.
//
//*****************************************************************************
extern void Interrupt_enable(uint32_t interruptNumber);

//*****************************************************************************
//
//! Disables an interrupt.
//!
//! \param interruptNumber specifies the interrupt to be disabled.
//!
//! The specified interrupt is disabled in the interrupt controller.  Other
//! enables for the interrupt (such as at the peripheral level) are unaffected
//! by this function.
//!
//! The available \e interruptNumber values are supplied in
//! <tt>inc/hw_ints.h</tt>.
//!
//! \return None.
//
//*****************************************************************************
extern void Interrupt_disable(uint32_t interruptNumber);

#ifdef __cplusplus
}
#endif

#endif // INTERRUPT_H
